package com.upb.webserver.common;

import com.fasterxml.jackson.databind.JsonNode;
import com.upb.webserver.common.exception.WebServerException;
import com.upb.webserver.common.returncode.ConstantCode;
import com.upb.webserver.common.tools.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.util.stream.Collectors;

@Slf4j
@Aspect
@Component
@Order(2)
public class ValidateBindingResult {


    @Pointcut("execution(public * com.upb.webserver.*.*Controller.*(..))")
    public void common() {
    }

    @Pointcut("execution(public * com.upb.webserver.*.*.*Controller.*(..))")
    public void common1() {

    }


    /**
     * 在切入点开始处切入内容
     *
     * @param joinPoint
     */
    @Around("common()||common1()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取所有的请求参数
        Object[] args = joinPoint.getArgs();
        if (null != args && args.length > 0) {
            for (Object obj : args) {
                if (obj instanceof BindingResult) {
                    // 参数验证
                    validate((BindingResult) obj);
                    break;
                }
            }
        }
        return joinPoint.proceed(); //调用目标方法
    }

    /**
     * 验证
     *
     * @param result
     * @return
     */
    private void validate(BindingResult result) {
        if (result.hasErrors()) {
            String errFieldStr = result.getAllErrors().stream()
                    .map(obj -> JsonUtils.stringToJsonNode(JsonUtils.objToString(obj)))
                    .map(err -> err.findValuesAsText("defaultMessage").toString())
                    .collect(Collectors.joining(","));
            StringUtils.removeEnd(errFieldStr, ",");
            String message = "these fields not match:" + errFieldStr;
            throw new WebServerException(ConstantCode.PARAM_EXCEPTION.getCode(), message);
        }
    }
}
